﻿using System;
using Assets.Scripts.Enums;
using UnityEngine;
using Object = UnityEngine.Object;

namespace Assets.Scripts.UI
{
    public abstract class Control
    {
        public UserInterface Ui { get; private set; }
        public string UiPath { get; }
        public string Name { get; }
        public object Data { get; set; }
        public UiType UiType { get; }
        public UiMode UiMode { get; }
        protected bool IsActived { get; private set; }
        public GameObject GameObj { get; set; }
        protected Control(UiType type, UiMode mode, string path)
        {
            UiType = type;
            UiMode = mode;
            UiPath = path;
            Name = GetType().ToString();
            Load();
        }

        private void Load()
        {
            if (GameObj == null && string.IsNullOrEmpty(UiPath) == false)
            {
                GameObj = Object.Instantiate(Resources.Load<GameObject>(UiPath));
                GameObj.SetActive(false);
                AnchorUi(GameObj);
            }
        }
        public void ScreenKeyPress(KeyInfo key)
        {

            IInputHandler handler = this as IInputHandler;

            if (handler != null)
            {
                if (key.Down)
                {
                    handler.KeyDown(key);
                }
                else
                {
                    handler.KeyUp(key);
                }
            }

        }

        internal bool CheckIfNeedBack()
        {
            if (UiType == UiType.Fixed || UiType == UiType.PopUp || UiType == UiType.None)
                return false;
            if (UiMode == UiMode.NoNeedBack || UiMode == UiMode.DoNothing)
                return false;
            return true;
        }

        public void Show(UserInterface ui)
        {
            Ui = ui;
            Active();
            Refresh();
            ui.PopNode(this);
        }

        public void Hide()
        {
            Deactive();
            Data = null;
        }

        public bool IsActive()
        {
            bool result = GameObj != null && GameObj.activeSelf;
            return result || IsActived;
        }

        public virtual void Active()
        {
            GameObj?.SetActive(true);
            IsActived = true;
        }

        public virtual void Deactive()
        {
            GameObj?.SetActive(false);
            IsActived = false;
        }

        public virtual void Init() { }
        public virtual void Refresh() { }
        public virtual void End() { }

        private void AnchorUi(GameObject ui)
        {
            GameObj = ui;

            Vector3 anchorPos;
            Vector2 sizeDel = Vector2.zero;
            Vector3 scale;
            if (ui.GetComponent<RectTransform>() != null)
            {
                anchorPos = ui.GetComponent<RectTransform>().anchoredPosition;
                sizeDel = ui.GetComponent<RectTransform>().sizeDelta;
                scale = ui.GetComponent<RectTransform>().localScale;
            }
            else
            {
                anchorPos = ui.transform.localPosition;
                scale = ui.transform.localScale;
            }


            switch (UiType)
            {
                case UiType.Normal:
                    ui.transform.SetParent(UiRoot.Get.transform.Find(SubRoot.NormalRoot.ToString()).transform);
                    break;
                case UiType.Fixed:
                    ui.transform.SetParent(UiRoot.Get.transform.Find(SubRoot.FixedRoot.ToString()).transform);
                    break;
                case UiType.PopUp:
                    ui.transform.SetParent(UiRoot.Get.transform.Find(SubRoot.PopUpRoot.ToString()).transform);
                    break;
                default:
                    throw new ArgumentOutOfRangeException($"obj is not in UiType");
            }


            if (ui.GetComponent<RectTransform>() != null)
            {
                ui.GetComponent<RectTransform>().anchoredPosition = anchorPos;
                ui.GetComponent<RectTransform>().sizeDelta = sizeDel;
                ui.GetComponent<RectTransform>().localScale = scale;
            }
            else
            {
                ui.transform.localPosition = anchorPos;
                ui.transform.localScale = scale;
            }
        }
    }

}
